package org.dingfugui.triple.protocol.binary.aio;

import org.dingfugui.triple.common.Logger;
import org.dingfugui.triple.common.LoggerFactory;
import org.dingfugui.triple.connection.AsyncConnection;
import org.dingfugui.triple.connection.Connection;
import org.dingfugui.triple.connection.Reader;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * Created by fugui.ding on 2015/6/10.
 */
public class AioConsumerConnection implements Connection, AsyncConnection {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    private final AsynchronousSocketChannel socket;

    public AioConsumerConnection(AsynchronousSocketChannel socket) {
        this.socket = socket;
    }

    @Override
    public Reader asyncRead() {

        ByteBuffer bb = ByteBuffer.allocate(1024);
        Future<Integer> future = socket.read(bb);

        Reader reader = new Reader(future, bb);

        return reader;
    }

    @Override
    public byte[] read() {
        try {
            ByteBuffer bb = ByteBuffer.allocate(1024);
            socket.read(bb).get();
            bb.flip();
            byte[] result = new byte[bb.limit()];

            bb.get(result, 0, bb.limit());
            logger.trace("读取返回报文长度:{}", result.length);
            return result;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void write(byte[] data) {
        try {
            logger.trace("发送请求报文长度:{}", data.length);
            socket.write(ByteBuffer.wrap(data)).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void close() {
        try {
            logger.debug("关闭消费者连接");
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean isClose() {
        return !socket.isOpen();
    }

}

